﻿using System;
using System.Collections;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace ZYCommon
{
    

    public class ZYErrorReport
    {
        public Image AppImage = null;
        private bool bolGetDebugPrint = false;
        public string LogFile = null;
        public DateTime LogTime = DateTime.Now;
        public string MemberName = null;
        private NameValueList myAttributes = new NameValueList();
        private ConsoleBuffer myDebugPrintBuffer = new ConsoleBuffer();
        private static ZYErrorReport myInstance = new ZYErrorReport();
        public string OperatorName = "";
        public string ReportURL = null;
        public Exception SourceException = null;
        public object SourceObject = null;
        public Type SourceType = null;
        public string SystemName = "";
        public string UserMessage = null;

        public void Clear()
        {
            this.SourceType = null;
            this.MemberName = null;
            this.SourceException = null;
            this.myAttributes.Clear();
            this.LogTime = DateTime.Now;
        }

        public void ClearDebugPrint()
        {
            this.myDebugPrintBuffer.Clear();
        }

        public string CreateReportXML(bool bolIndent)
        {
            StringWriter w = new StringWriter();
            XmlTextWriter myXMLWriter = new XmlTextWriter(w);
            if (bolIndent)
            {
                myXMLWriter.Formatting = Formatting.Indented;
                myXMLWriter.IndentChar = ' ';
                myXMLWriter.Indentation = 4;
            }
            this.CreateReportXML(myXMLWriter);
            myXMLWriter.Flush();
            string str = w.ToString();
            myXMLWriter.Close();
            int index = str.IndexOf("?>");
            if (index > 0)
            {
                str = str.Substring(index + 2);
            }
            return str;
        }

        public void CreateReportXML(XmlTextWriter myXMLWriter)
        {
            myXMLWriter.WriteStartDocument();
            myXMLWriter.WriteStartElement("errorreport");
            myXMLWriter.WriteAttributeString("version", "1.0");
            myXMLWriter.WriteElementString("报告器版本", base.GetType().AssemblyQualifiedName);
            myXMLWriter.WriteElementString("报告器位置", base.GetType().Assembly.Location);
            myXMLWriter.WriteElementString("来源", base.GetType().Assembly.CodeBase);
            myXMLWriter.WriteElementString("报告时间", this.LogTime.ToString("yyyy-MM-dd HH:mm:ss"));
            myXMLWriter.WriteElementString("系统名称", this.SystemName);
            myXMLWriter.WriteElementString("当前用户", this.OperatorName);
            myXMLWriter.WriteElementString("用户信息", this.UserMessage);
            if (this.MemberName != null)
            {
                myXMLWriter.WriteElementString("发生错误的对象成员名称", this.MemberName);
            }
            if (this.SourceException != null)
            {
                myXMLWriter.WriteStartElement("用户错误");
                myXMLWriter.WriteCData(this.SourceException.ToString());
                myXMLWriter.WriteEndElement();
            }
            if (this.myAttributes.Count > 0)
            {
                myXMLWriter.WriteStartElement("报告属性");
                for (int i = 0; i < this.myAttributes.Count; i++)
                {
                    myXMLWriter.WriteStartElement("value");
                    myXMLWriter.WriteAttributeString("name", this.myAttributes.GetName(i));
                    myXMLWriter.WriteAttributeString("value", this.myAttributes.GetValue(i));
                    myXMLWriter.WriteEndElement();
                }
                myXMLWriter.WriteEndElement();
            }
            myXMLWriter.WriteStartElement("系统调试输出信息");
            myXMLWriter.WriteCData(this.myDebugPrintBuffer.ToString());
            myXMLWriter.WriteEndElement();
            myXMLWriter.WriteStartElement("系统环境");
            myXMLWriter.WriteCData(this.GetEnvironmentDesc());
            myXMLWriter.WriteEndElement();
            if (this.SourceObject != null)
            {
                this.SourceType = this.SourceObject.GetType();
            }
            if (this.SourceType != null)
            {
                myXMLWriter.WriteStartElement("发生错误的类型");
                myXMLWriter.WriteAttributeString("名称", this.SourceType.Name);
                myXMLWriter.WriteAttributeString("程序集", this.SourceType.Assembly.FullName);
                myXMLWriter.WriteStartElement("成员列表");
                foreach (MemberInfo info in this.SourceType.GetMembers(BindingFlags.CreateInstance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance))
                {
                    bool flag = false;
                    try
                    {
                        ParameterInfo[] infoArray2 = null;
                        if (info is FieldInfo)
                        {
                            flag = true;
                            FieldInfo info2 = info as FieldInfo;
                            myXMLWriter.WriteStartElement("字段");
                            myXMLWriter.WriteAttributeString("name", info.Name);
                            if (this.SourceObject != null)
                            {
                                myXMLWriter.WriteAttributeString("数值", (info2.GetValue(this.SourceObject) == null) ? "[null]" : info2.GetValue(this.SourceObject).ToString());
                            }
                            myXMLWriter.WriteAttributeString("类型", info2.FieldType.ToString());
                            myXMLWriter.WriteStartAttribute("属性", null);
                            if (info2.IsInitOnly)
                            {
                                myXMLWriter.WriteString(" initonly ");
                            }
                            if (info2.IsPrivate)
                            {
                                myXMLWriter.WriteString(" private ");
                            }
                            if (info2.IsPublic)
                            {
                                myXMLWriter.WriteString(" public ");
                            }
                            if (info2.IsSpecialName)
                            {
                                myXMLWriter.WriteString(" specialname ");
                            }
                            if (info2.IsStatic)
                            {
                                myXMLWriter.WriteString(" static ");
                            }
                            myXMLWriter.WriteEndAttribute();
                        }
                        if (info is PropertyInfo)
                        {
                            flag = true;
                            PropertyInfo info3 = info as PropertyInfo;
                            myXMLWriter.WriteStartElement("属性");
                            myXMLWriter.WriteAttributeString("name", info.Name);
                            if ((this.SourceObject != null) && info3.CanRead)
                            {
                                myXMLWriter.WriteAttributeString("数值", (info3.GetValue(this.SourceObject, null) == null) ? "[null]" : info3.GetValue(this.SourceObject, null).ToString());
                            }
                            myXMLWriter.WriteAttributeString("类型", info3.PropertyType.ToString());
                            myXMLWriter.WriteStartAttribute("属性", null);
                            if (info3.CanRead)
                            {
                                myXMLWriter.WriteString(" read ");
                            }
                            if (info3.CanWrite)
                            {
                                myXMLWriter.WriteString(" write ");
                            }
                            if (info3.IsSpecialName)
                            {
                                myXMLWriter.WriteString(" specialname ");
                            }
                            myXMLWriter.WriteEndAttribute();
                        }
                        if (infoArray2 != null)
                        {
                            foreach (ParameterInfo info4 in infoArray2)
                            {
                                myXMLWriter.WriteStartElement("参数");
                                myXMLWriter.WriteAttributeString("名称", info4.Name);
                                myXMLWriter.WriteAttributeString("类型", info4.ParameterType.ToString());
                                myXMLWriter.WriteStartAttribute("属性", null);
                                if (info4.IsOptional)
                                {
                                    myXMLWriter.WriteString(" optional ");
                                }
                                if (info4.IsOut)
                                {
                                    myXMLWriter.WriteString(" out ");
                                }
                                if (info4.IsIn)
                                {
                                    myXMLWriter.WriteString(" in ");
                                }
                                if (info4.IsRetval)
                                {
                                    myXMLWriter.WriteString(" retval ");
                                }
                                myXMLWriter.WriteEndAttribute();
                                myXMLWriter.WriteEndElement();
                            }
                        }
                    }
                    catch (Exception exception)
                    {
                        myXMLWriter.WriteString("获取成员信息错误:" + exception.Message);
                    }
                    if (flag)
                    {
                        myXMLWriter.WriteEndElement();
                    }
                }
            }
            myXMLWriter.WriteEndElement();
            myXMLWriter.WriteEndDocument();
        }

        public void DebugPrint(string strText)
        {
            if (strText.Length > 0x7d0)
            {
                Console.WriteLine(strText.Substring(0, 0x7d0));
            }
            else
            {
                Console.WriteLine(strText);
            }
            if (this.bolGetDebugPrint)
            {
                this.myDebugPrintBuffer.WriteLine(strText);
            }
        }

        public string GetEnvironmentDesc()
        {
            StringBuilder builder = new StringBuilder();
            string executablePath = Application.ExecutablePath;
            builder.Append("\r\n 主程序:" + executablePath);
            try
            {
                FileInfo info = new FileInfo(executablePath);
                builder.Append("\r\n 主程序信息 创建时间:" + info.CreationTime.ToString("yyyy-MM-dd HH:mm:ss"));
                builder.Append(" 修改时间:" + info.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss"));
                builder.Append(" 最后读取时间:" + info.LastAccessTime.ToString("yyyy-MM-dd HH:mm:ss"));
                builder.Append(" 文件属性:" + info.Attributes.ToString());
                builder.Append(" 长度:" + info.Length.ToString());
            }
            catch (Exception exception)
            {
                builder.Append("获取文件 " + executablePath + " 信息时错误" + exception.ToString());
            }
            try
            {
                builder.Append("\r\n 主程序名称:" + Application.ProductName);
                builder.Append("\r\n 主程序版本:" + Application.ProductVersion);
                builder.Append("\r\n 时间擢    :" + Environment.TickCount);
                builder.Append("\r\n 命令行    :" + Environment.CommandLine);
                builder.Append("\r\n 当前目录  :" + Environment.CurrentDirectory);
                builder.Append("\r\n 计算机名  :" + Environment.MachineName);
                builder.Append("\r\n 操作系统  :" + Environment.OSVersion.ToString());
                builder.Append("\r\n 系统目录  :" + Environment.SystemDirectory);
                builder.Append("\r\n 网络域名  :" + Environment.UserDomainName);
                builder.Append("\r\n 互换模式  :" + Environment.UserInteractive);
                builder.Append("\r\n 用户名    :" + Environment.UserName);
                builder.Append("\r\n 运行库    :" + Environment.Version);
                builder.Append("\r\n 所用物理内存:" + Environment.WorkingSet);
                builder.Append("\r\n 环境变量 -----------------------------------");
                IDictionaryEnumerator enumerator = Environment.GetEnvironmentVariables().GetEnumerator();
                while (enumerator.MoveNext())
                {
                    builder.Append(string.Concat(new object[] { "\r\n     ", enumerator.Key, "=", enumerator.Value }));
                }
                builder.Append("\r\n 当前进程信息 -------------------------------");
                Process currentProcess = Process.GetCurrentProcess();
                currentProcess.Refresh();
                builder.Append("\r\n     优先级   :" + currentProcess.BasePriority);
                builder.Append("\r\n     句柄     :" + currentProcess.Handle);
                builder.Append("\r\n     句柄计数 :" + currentProcess.HandleCount);
                builder.Append("\r\n     进程编号 :" + currentProcess.Id);
                builder.Append("\r\n     进程名   :" + currentProcess.ProcessName);
                builder.Append("\r\n     主模块   :" + currentProcess.MainModule);
                //builder.Append("\r\n     虚拟内存 :" + currentProcess.VirtualMemorySize);
                //builder.Append("\r\n     物理内存 :" + currentProcess.WorkingSet);
                builder.Append("\r\n     启动时间 :" + currentProcess.StartTime);
                builder.Append("\r\n     已运行时间    :" + ((TimeSpan) (DateTime.Now - currentProcess.StartTime)));
                builder.Append("\r\n     主窗体句柄    :" + currentProcess.MainWindowHandle);
                builder.Append("\r\n     主窗体标题    :" + currentProcess.MainWindowTitle);
                //builder.Append("\r\n     工作集峰值    :" + currentProcess.PeakWorkingSet);
                builder.Append("\r\n     允许最大工作集:" + currentProcess.MaxWorkingSet);
                builder.Append("\r\n     允许最小工作集:" + currentProcess.MinWorkingSet);
                //builder.Append("\r\n     虚拟内存峰值  :" + currentProcess.PeakVirtualMemorySize);
                //builder.Append("\r\n     专用内存大小  :" + currentProcess.PrivateMemorySize);
                builder.Append("\r\n     总处理器时间  :" + currentProcess.TotalProcessorTime);
                builder.Append("\r\n     用户处理器时间:" + currentProcess.UserProcessorTime);
            }
            catch (Exception exception2)
            {
                builder.Append("\r\n 读取系统信息错误" + exception2.ToString());
            }
            return builder.ToString();
        }

        private byte[] PostReportData(byte[] bytSend)
        {
            return CommonFunction.HttpPostData(this.ReportURL, bytSend, null, null);
        }

        public void ReportError()
        {
            this.ShowErrorDialog();
            this.Clear();
        }

        public bool SendReportError()
        {
            bool flag=false;
            if (StringCommon.isBlankString(this.ReportURL))
            {
                return false;
            }
            try
            {
                ArrayList httpPostEncoding = XMLHttpConnection.GetHttpPostEncoding(new HttpPostDataHandler(this.PostReportData));
                if (httpPostEncoding == null)
                {
                    return false;
                }
                string s = this.CreateReportXML(false);
                byte[] bytes = (httpPostEncoding[0] as Encoding).GetBytes(s);
                this.PostReportData(bytes);
                this.Clear();
                flag = true;
            }
            catch
            {
            }
            return flag;
        }

        public void SetAttribute(string strName, string strValue)
        {
            this.myAttributes.SetValue(strName, strValue);
        }

        public void ShowErrorDialog()
        {
            //using (dlgError error = new dlgError())
            //{
            //    error.ErrorReport = this;
            //    error.ShowDialog();
            //}
        }

        public ConsoleBuffer DebugPrintBuffer
        {
            get
            {
                return this.myDebugPrintBuffer;
            }
        }

        public bool GetDebugPrint
        {
            get
            {
                return this.bolGetDebugPrint;
            }
            set
            {
                this.bolGetDebugPrint = value;
            }
        }

        public static ZYErrorReport Instance
        {
            get
            {
                return myInstance;
            }
        }
    }
}

